package com.wwj.admin.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageInfo;
import com.wwj.admin.Vo.CodeVo;
import com.wwj.admin.Vo.UserVo;
import com.wwj.admin.constant.ConstantFinal;
import com.wwj.admin.entity.UserEntity;
import com.wwj.admin.exception.OpenFeignException;
import com.wwj.admin.feign.ExpressFeignService;
import com.wwj.admin.feign.QuestionFeignService;
import com.wwj.admin.feign.SendFeignService;
import com.wwj.admin.service.UserService;
import com.wwj.common.constant.CommonCodeEnum;
import com.wwj.common.constant.CommonConstant;
import com.wwj.common.entitiy.R;
import com.wwj.common.utils.JWTUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;

@RestController
@Slf4j
@RequestMapping("/admin")
public class AdminController {

    @Resource
    private UserService userService;

    @Resource
    private ExpressFeignService expressFeignService;

    @Resource
    private QuestionFeignService questionFeignService;

    @Resource
    private SendFeignService sendFeignService;

    /**
     * 验证码服务
     * http://127.0.0.1:88/api/admin/getIdentifyCode?time=1664336088268&codeUUID=xxxxx
     */
    @RequestMapping("/getIdentifyCode")
    public R<CodeVo> getIdentifyCode(String codeUUID) {
        CodeVo codeVo;
        // 表示之前获取过验证码
        if (codeUUID != null) {
            codeVo = userService.againCreateCode(codeUUID);
        } else {
            // 表示第一次获取验证码
            codeVo = userService.createCode();
        }
        return R.ok(codeVo);
    }

    /**
     * 登录服务
     * http://127.0.0.1:88/api/admin/login
     */
    @PostMapping("/login")
    @ResponseBody
    public R<Object> login(@Valid @RequestBody UserVo userVo, BindingResult result) {
        if (result.hasErrors()) {
            // JSR303校验失败
            Map<String, String> map = new HashMap<>();
            result.getFieldErrors().forEach(item -> {
                String message = item.getDefaultMessage();
                String field = item.getField();
                map.put(field, message);
            });
            log.info(userVo + "======》" + "JSR303校验失败");
            return R.error(CommonCodeEnum.VALIDATION_ERROR.getCode(), CommonCodeEnum.VALIDATION_ERROR.getMsg(), map);
        } else if (!(userService.checkCode(userVo))) {
            // 验证码校验失败
            log.info(userVo + "======》" + "验证码校验失败");
            return R.error(CommonCodeEnum.IDENTIFY_CODE_ERROR.getCode(), CommonCodeEnum.IDENTIFY_CODE_ERROR.getMsg());
        } else {
            // todo 后期可以优化MD5盐值加密
            // 数据库校验
            QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(ConstantFinal.FIELD_USER_ID, userVo.getUserId())
                    .eq(ConstantFinal.FIELD_USER_IDENTITY,ConstantFinal.VALUE_ADMIN)
                    .eq(ConstantFinal.FIELD_USER_PASSWORD, userVo.getUserPassword())
                    .eq(ConstantFinal.FIELD_USER_IDENTITY, ConstantFinal.VALUE_ADMIN);
            UserEntity userQueryResult = userService.getOne(queryWrapper);
            if (userQueryResult == null) {
                log.info(userVo + "======》" + "登录失败");
                return R.error(CommonCodeEnum.PASSWORD_ACCOUNT_ERROR.getCode(), CommonCodeEnum.PASSWORD_ACCOUNT_ERROR.getMsg());
            } else {
                log.info(userVo + "======》" + "登录成功");
                // 登录成功，发token
                JWTUtils jwtUtils = new JWTUtils();
                // 设置签名
                jwtUtils.setSignature(CommonConstant.ADMIN_TOKEN);
                String adminToken = jwtUtils.createUserToken(userQueryResult.getUserId());
                // 存储token
                return R.ok(CommonCodeEnum.SUCCESS.getCode(), CommonCodeEnum.SUCCESS.getMsg(), new UserVo(
                        userQueryResult.getUserId(),
                        userQueryResult.getUserPassword(),
                        null,
                        userQueryResult.getUserName(),
                        adminToken,
                        null,
                        null));
            }
        }
    }

    /**
     * 后台管理员退出登录
     * http://127.0.0.1:88/api/admin/exitLogin
     */
    @RequestMapping("/exitLogin")
    public R<Object> exitLogin(HttpServletRequest request) {
        // todo 后期可以抽取一个方法
        // 解析token
        String token = request.getHeader(ConstantFinal.REQUEST_HEADER_TOKEN);
        log.info("需要退出登录的token数据 ======》" + token);
        JWTUtils jwtUtils = new JWTUtils();
        jwtUtils.setSignature(CommonConstant.ADMIN_TOKEN);
        Claims claims = jwtUtils.parseToken(token);
        Date expiration = claims.getExpiration();
        if (jwtUtils.judgeTokenExpiration(expiration)) {
            log.info("===token失效==");
            return R.error(CommonCodeEnum.TOKEN_OUTDATED.getCode(), CommonCodeEnum.TOKEN_OUTDATED.getMsg());
        } else {
            log.info("===成功退出登录===");
            return R.ok(CommonCodeEnum.SUCCESS.getMsg());
        }
    }

    /**
     * 根据用户id查询是否存在此用户
     * OpenFeign
     */
    @GetMapping("/selectUserExist")
    public R<Object> selectUserExist(@RequestParam("userId") String userId){
        QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ConstantFinal.FIELD_USER_ID, userId).ne(ConstantFinal.FIELD_USER_IDENTITY, ConstantFinal.VALUE_ADMIN); // 不能等于管理员的身份
        UserEntity user = userService.getOne(queryWrapper);
        if (user != null){
            return R.ok("存在");
        }else {
            return R.error("不存在");
        }
    }

    /**
     * 根据用户id查询用户的详细信息
     * OpenFeign
     */
    @GetMapping("/getUserById")
    public R<UserEntity> getUserById(@RequestParam("userId") String userId){
        UserEntity userEntity = userService.getById(userId);
        if (userEntity == null) {
            return R.error(CommonCodeEnum.ERROR.getCode(), CommonCodeEnum.ERROR.getMsg());
        }else {
            return R.ok(CommonCodeEnum.SUCCESS.getCode(),CommonCodeEnum.SUCCESS.getMsg(),userEntity);
        }
    }

    /**
     * 获取全部用户的数据
     * http://127.0.0.1:88/api/admin/getUserData
     */
    @GetMapping("/getUserData/{currentPage}/{pageSize}")
    public R<Object> getUserData(@PathVariable("currentPage") String currentPage,
                                  @PathVariable("pageSize") String pageSize,
                                  @RequestParam("query") String query){
        PageInfo<UserEntity> pageInfo = userService.getUserData(currentPage,pageSize,query);
        return R.ok(CommonCodeEnum.SUCCESS.getCode(),CommonCodeEnum.SUCCESS.getMsg(),pageInfo);
    }

    /**
     * 删除单个用户
     * http://127.0.0.1:88/api/admin/removeOne?userId=1231231
     */
    @DeleteMapping("/removeOne")
    public R<Object> removeOne(@RequestParam("userId") String userId) {
        List<String> ids = new ArrayList<>();
        ids.add(userId);
        if(this.userExist(ids)){
            boolean flag = userService.removeById(userId);
            if (flag) {
                return R.ok("移除成功");
            }else {
                return R.error("移除失败");
            }
        }else {
            return R.error(CommonCodeEnum.USER_EXIST.getCode(), CommonCodeEnum.USER_EXIST.getMsg());
        }
    }

    /**
     * 更新用户数据
     * http://127.0.0.1:88/api/admin/update
     */
    @PutMapping("/update")
    public R<Object> update(@RequestBody UserEntity userEntity){
        boolean flag = userService.updateById(userEntity);
        if (flag){
            return R.ok("更新成功");
        }else {
            return R.error("更新失败");
        }
    }

    /**
     * 新增用户
     * http://127.0.0.1:88/api/admin/add
     */
    @PostMapping("/add")
    public R<Object> add(@RequestBody UserEntity userEntity) {
        // 判断是否有相同的主键
        QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ConstantFinal.FIELD_USER_ID,userEntity.getUserId());
        UserEntity queryResult = userService.getOne(queryWrapper);
        if (queryResult != null) {
            return R.error(CommonCodeEnum.USER_EXIST.getCode(), "用户存在不能添加");
        }
        boolean flag = userService.save(userEntity);
        if (flag){
            return R.ok("新增成功");
        }else {
            return R.error("新增失败");
        }
    }

    /**
     * 批量删除用户
     *  http://127.0.0.1:88/api/admin/batchDelete
     */
    @DeleteMapping("/batchDelete")
    public R<Object> batchDelete(@RequestBody List<UserEntity> list){
        // 抽取ids
        List<String> ids = new ArrayList<>();
        list.forEach(item -> {
            ids.add(item.getUserId());
        });
        // 判断是否可以删除
        if(this.userExist(ids)){
            // 删除
            boolean flag = userService.removeByIds(ids);
            if (flag){
                return R.ok("批量删除成功");
            }else {
                return R.error("批量删除失败");
            }
        }else {
            return R.error(CommonCodeEnum.USER_EXIST.getCode(), CommonCodeEnum.USER_EXIST.getMsg());
        }
    }

    /**
     * 查询各个数据库是否有该用户存在
     */
    public boolean userExist(List<String> ids){
        try{
            R<Object> r1 = expressFeignService.userIdExist(ids);
            R<Object> r2 = questionFeignService.userExist(ids);
            R<Object> r3 = sendFeignService.userExist(ids);
            return r1.getCode() == CommonCodeEnum.SUCCESS.getCode() && r2.getCode() == CommonCodeEnum.SUCCESS.getCode() && r3.getCode() == CommonCodeEnum.SUCCESS.getCode();
        }catch (OpenFeignException e){
            e.printStackTrace();
            return false;
        }
    }
}
